package com.mti.controller;


import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mti.component.ResponseCallBack;
import com.mti.component.ResponseCriteria;
import com.mti.component.ResponseInfo;
import com.mti.dao.model.LfZdryApproveLogEntity;
import com.mti.dao.model.LfZdryEntity;
import com.mti.dao.qo.LfZdryQO;
import com.mti.exception.BusinessException;
import com.mti.service.ILfGkjlService;
import com.mti.service.ILfZdryService;
import com.mti.service.ISpecialPersonService;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @company 上海道枢信息科技-->
 * @anthor created by zhangmingxin
 * @date 2019/8/15
 * @change
 * @describe describe
 **/
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping(value = "/specialPerson")
@Api(value = "重点人员模块",description = "重点人员模块")
public class SpecialPersonController {
    private final ISpecialPersonService service;
    private final ILfZdryService zdryService;
    private final ILfGkjlService gkjlService;

    @ApiOperation(value = "分页获取重点人员信息")
    @GetMapping("/page/list")
    public Mono<ResponseInfo> listSpecialPersons(
            @RequestParam(value = "page")@ApiParam(value = "当前页",name = "page",required = true) Integer page,
            @RequestParam(value = "size")@ApiParam(value = "页大小",name = "size",required = true)Integer size,
            @RequestParam(value = "date")@ApiParam(value = "日期(格式：yyyy-MM-dd)",name = "date",required = true) String date,
            @RequestParam(value = "zrbm",required = false)@ApiParam(value = "责任单位",name = "zrbm") String zrbm,
            @RequestParam(value = "rangeVal",required = false)@ApiParam(value = "范围值",name = "rangeVal")String rangeVal,
            @RequestParam(value = "rangeType",required = false)@ApiParam(value = "范围类型(1:市局,2:分局,3:派出所(多个派出所ID用英文逗号分隔),)",name = "rangeType")String rangeType
    )  {
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                if (StringUtils.isEmpty(date))
                    throw new BusinessException(500,"The argument date cannot be null!");
                IPage iPage = service.pageDataV2(page, size, date, rangeVal, rangeType,zrbm);
                criteria.addMapResult("record",iPage.getRecords());
                criteria.addMapResult("total",iPage.getTotal());
                criteria.addMapResult("zk",service.getIsControlCountByVersionV2(date, zrbm, rangeVal, rangeType, "1"));
                criteria.addMapResult("sk",service.getIsControlCountByVersionV2(date, zrbm, rangeVal, rangeType, "0"));
                criteria.addMapResult("wsb",service.getIsControlCountByVersionV2(date, zrbm, rangeVal, rangeType, "2"));
            }
        }.sendRequest());
    }


    @ApiOperation(value = "分页获取统计重点人员数据列表信息")
    @GetMapping("/page/statistics/list")
    public Mono<ResponseInfo> listStatisticsSpecialPersons(
            @RequestParam(value = "page")@ApiParam(value = "当前页",name = "page",required = true) Integer page,
            @RequestParam(value = "size")@ApiParam(value = "页大小",name = "size",required = true)Integer size,
            @RequestParam(value = "rangeVal",required = false)@ApiParam(value = "范围值",name = "rangeVal")String rangeVal,
            @RequestParam(value = "rangeType",required = false)@ApiParam(value = "范围类型(1:市局,2:分局、派出所(多个派出所ID用英文逗号分隔),)",name = "rangeType")String rangeType,
            @RequestParam(value = "zrbm",required = false)@ApiParam(value = "责任部门",name = "zrbm")String zrbm,
            @RequestParam(value = "isApproveFilter",required = false)@ApiParam(value = "是否使用状态筛选(0:不使用,1:使用)",name = "isApproveFilter")String isApproveFilter,
            @RequestParam(value = "start",required = false)@ApiParam(value = "开始时间(yyyyMMddhhmmss)",name = "start")String start,
            @RequestParam(value = "end",required = false)@ApiParam(value = "结束时间(yyyyMMddhhmmss)",name = "end")String end
    )  {
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                IPage<LfZdryEntity> iPage = zdryService.listStatisticsPage(page, size, rangeVal, rangeType,zrbm,isApproveFilter,start,end);
                criteria.addMapResult("record",iPage.getRecords());
                criteria.addMapResult("total",iPage.getTotal());
            }
        }.sendRequest());
    }

    @ApiOperation(value = "导出重点人员信息为Excel")
    @PostMapping("/excel/export")
    public Mono<Void> downloadByWriteWith(@RequestBody LfZdryQO qo,
                                          @RequestParam(value = "date",required = false)@ApiParam(value = "日期(格式：yyyy-MM-dd)",name = "date") String date,
                                          @RequestParam(value = "exportName",required = false)@ApiParam(value = "导出表头名称",name = "exportName") String exportName,
                                          ServerHttpResponse response, ServerWebExchange exchange
    ) throws Exception {
            if(null ==date) date=LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String fileName = StringUtils.isEmpty(exportName) ? "重点人每日隐患状态上报表(" + LocalDate.parse(date).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")" : exportName;
            String fn = new String(fileName.getBytes(), "iso8859-1");
            log.info("fileName==>{}",fileName);
            response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fn + ".xlsx");
            response.getHeaders().add("Accept-Ranges", "bytes");
            Mono<DataBuffer> flux = service.export(date, exportName,qo,exchange);
            return response.writeWith(flux);
    }

    @ApiOperation(value = "根据身份证号导出重点人员信息为Excel")
    @PostMapping("/excel/export/number")
    public Mono<Void> downloadByWriteWithNumber(@RequestBody Map<String,Object> listNumbers,
                                          @RequestParam(value = "date",required = false)@ApiParam(value = "日期(格式：yyyy-MM-dd)",name = "date") String date,
                                          @RequestParam(value = "exportName",required = false)@ApiParam(value = "导出表头名称",name = "exportName") String exportName,
                                          ServerHttpResponse response, ServerWebExchange exchange
    ) throws Exception {
        if(null ==date) date=LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String fileName = StringUtils.isEmpty(exportName) ? "重点人每日隐患状态上报表(" + LocalDate.parse(date).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")" : exportName;
        String fn = new String(fileName.getBytes(), "iso8859-1");
        log.info("fileName==>{}",fileName);
        response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fn + ".xlsx");
        response.getHeaders().add("Accept-Ranges", "bytes");
        List<String> listNumber =(List<String>)listNumbers.get("listNumber");
        Mono<DataBuffer> flux = service.export1(listNumber,date, exportName,exchange);
        return response.writeWith(flux);
    }

//    @GetMapping(value = "/statistics")
//    @ApiOperation(value = "获取市局、分局统计数据")
//    public Mono<ResponseInfo> getStatisticsData(@RequestParam(value = "rangeType",required = false)@ApiParam(value = "范围类型(1:市局,2:分局、派出所)",name = "rangeType")String rangeType,
//                                                @RequestParam(value = "rangeVal",required = false)@ApiParam(value = "范围值(多个派出所ID用英文逗号分隔)",name = "rangeVal")String rangeVal,
//                                                @RequestParam(value = "roleType",required = false)@ApiParam(value = "警种(多个警种用英文逗号分隔)",name = "roleType")String roleType){
//        return Mono.just(new ResponseCallBack() {
//            @Override
//            public void execute(ResponseCriteria criteria, Object... obj) {
//                criteria.addSingleResult(service.getSpecialPersonStatisticsData(rangeType, rangeVal,roleType));
//            }
//        }.sendRequest());
//    }


    @PostMapping(value = "/statistics")
    @ApiOperation(value = "获取市局、分局统计数据")
    public Mono<ResponseInfo> getStatisticsData(@RequestBody LfZdryQO qo){
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                if(null == qo){
                    throw  new BusinessException(99999,"请求入参错误");
                }
                criteria.addSingleResult(service.getSpecialPersonStatisticsData(qo));
            }
        }.sendRequest());
    }

    @GetMapping(value = "/predictStatistics")
    @ApiOperation(value = "获取预警统计数据")
    public Mono<ResponseInfo> getPredictAlarmStatistics(@RequestParam(value = "rangeType",required = false)@ApiParam(value = "范围类型(1:市局,2:分局、派出所)",name = "rangeType")String rangeType,
                                                        @RequestParam(value = "rangeVal",required = false)@ApiParam(value = "范围值(多个派出所ID用英文逗号分隔)",name = "rangeVal")String rangeVal,
                                                        @RequestParam(value = "start",required = false)@ApiParam(value = "开始时间(yyyyMMddhhmmSS)",name = "start")String start,
                                                        @RequestParam(value = "end",required = false)@ApiParam(value = "结束时间(yyyyMMddhhmmSS)",name = "end")String end){
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                criteria.addSingleResult(service.getPredictSpecialPersonStatisticsData(rangeType, rangeVal, start, end));
            }
        }.sendRequest());
    }

    @PostMapping(value = "/sign")
    @ApiOperation(value = "重点人员状态上报")
    public Mono<ResponseInfo> updateStatus(@RequestParam(value = "personId")@ApiParam(value = "人员ID",name = "personId",required = true) String personId,
                                           @RequestParam(value = "sfzk")@ApiParam(value = "是否在控(0:失控，1：在控)",name = "sfzk",required = true) String sfzk){
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                gkjlService.upZksk(personId,sfzk);
            }
        }.sendRequest());
    }

    @PostMapping(value = "/approve")
    @ApiOperation(value = "重点人员审批")
    public Mono<ResponseInfo> approveSpecialPerson(@RequestBody LfZdryApproveLogEntity zdryApproveLogEntity){
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                service.approveSpecialPerson(zdryApproveLogEntity);
            }
        }.sendRequest());
    }

    @PostMapping(value = "/importSp")
    @ApiOperation(value = "Excel导入重点人员")
    public ResponseInfo uploadFile(@RequestPart("file") FilePart file,ServerWebExchange exchange){
        /*return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                try {
                    ResponseInfo result = new ResponseInfo();
                    String str = (String) service.uploadSp(file,exchange);
                    if(str.indexOf("execl")>=0) result.setCode(201);
                    else result.setCode(200);
                    result.setData(str);
                    result.setMessage("成功");
                    criteria.addSingleResult(result);
                } catch (Exception e) {
                    throw new BusinessException(500,"上传时服务器内部发生异常");
                }
            }
        }.sendRequest();*/
        try {
            ResponseInfo result = new ResponseInfo();
            List<Object> str = (List<Object>) service.uploadSp(file,exchange);
            if(str.indexOf("execl")>=0) result.setCode(201);
            else result.setCode(200);
//            List<String> list = Arrays.asList(str.split(""));
            result.setData(str);
            result.setMessage("成功");
            return result;
        } catch (Exception e) {
            throw new BusinessException(500,"上传时服务器内部发生异常");
        }
    }

    @GetMapping(value = "/searchLngLat")
    @ApiOperation(value = "根据地址，具体返回经纬度")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "省",name = "province",dataType = "String",paramType = "query"),
            @ApiImplicitParam(value = "市",name = "city",dataType = "String",paramType = "query"),
            @ApiImplicitParam(value = "县",name = "country",dataType = "String",paramType = "query"),
            @ApiImplicitParam(value = "镇",name = "village",dataType = "String",paramType = "query")
    })
    public ResponseInfo searchLngLat(@RequestParam String province,@RequestParam String city,
                                     @RequestParam String country,@RequestParam String  village){
        return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                try {
                    criteria.addSingleResult(service.searchLngLat(province,city,country,village));
                } catch (Exception e) {
                    throw new BusinessException(500,"此地址未查询到经纬度！");
                }
            }
        }.sendRequest();
    }

    @ApiOperation(value = "市局管辖重点人员各风险等级数量统计",notes = "市局管辖重点人员各风险等级数量统计")
    @RequestMapping(value = "/getRiskLevelCount", method = RequestMethod.GET)
    public Mono<ResponseInfo> getRiskLevelCount(@RequestParam String sspcs,@RequestParam String ssxq,@RequestParam String rylb){
        return Mono.just(new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                List<Map<String, Object>> riskLevelCount = zdryService.getRiskLevelCount(sspcs,ssxq,rylb);
                criteria.addSingleResult(riskLevelCount);
            }
        }.sendRequest());
    }
}
